----------Sentence Diagramming---------
A 4am crack                  2016-02-23
---------------------------------------

Name: Sentence Diagramming
Genre: educational
Year: 1985
Authors: Dr. E. J. Franco
Publisher: Intellectual Software
Media: 4 single-sided 5.25-inch discs
OS: DOS 3.3
Previous cracks: none
Similar cracks:
  #604 American Government
  #592 Alphabetical Order
  #281 Flash Spell Helicopter

This appears to be a re-release of
"Diagramming Grammatical Relationships"
(#519) with an additional title page
and updated copy protection.

The manual refers to 5 disks, but I
only have 4. I'll start with disk 1.

                   ~

               Chapter 0
 In Which Various Automated Tools Fail
          In Interesting Ways


COPYA
  immediate disk read error

Locksmith Fast Disk Backup
  unable to read any track

EDD 4 bit copy (no sync, no count)
  works

Copy ][+ nibble editor
  modified prologues and epilogues
  address: "CD ** BC" / "BA FA **"
    (second prologue byte and third
     epilogue byte vary, even between
     different sectors on one track)
  data: "DE F7 E5" / "EC BD"

Disk Fixer
  ["O" -> "Input/Output Control"]
    set CHECKSUM ENABLED to "NO"
  T00,S00 readable
  rest of track $00 unreadable
  virtually impossible to read any
  tracks beyond T00, due to varying
  address prologue on every sector(!)

Why didn't COPYA work?
  modified prologues & epilogues

Why didn't Locksmith FDB work?
  ditto

EDD worked. What does that tell us?
  no half or quarter tracks
  almost certainly no nibble check
  (just structural changes to prologues
  and epilogues)

Next steps:

  1. capture RWTS with AUTOTRACE
  2. convert disk to standard format
     with Advanced Demuffin
  3. patch RWTS to read standard format

                   ~

               Chapter 1
      In Which We Dive Head First
       Into Unfriendly Territory


]PR#5
CAPTURING BOOT0
...reboots slot 6...
...reboots slot 5...
SAVING BOOT0

]CALL -151
*800<2800.28FFM
*801L

; non-standard from the get go
0801-   20 B3 08    JSR   $08B3

*8B3L

; change nibble table used by the disk
; controller ROM routine (this explains
; why I couldn't read the rest of track
; $00 with a sector editor)
08B3-   A9 3F       LDA   #$3F
08B5-   8D 6C 03    STA   $036C
08B8-   A9 1C       LDA   #$1C
08BA-   8D CC 03    STA   $03CC
08BD-   A9 00       LDA   #$00
08BF-   8D D5 03    STA   $03D5
08C2-   A9 37       LDA   #$37
08C4-   8D A3 03    STA   $03A3

; regular code from $0801
08C7-   A5 27       LDA   $27
08C9-   C9 09       CMP   #$09
08CB-   60          RTS

Continuing from $0804...

*804L

; standard DOS 3.3 bootloader
0804-   D0 19       BNE   $081F
0806-   EA          NOP
0807-   A5 2B       LDA   $2B
0809-   4A          LSR
080A-   4A          LSR
080B-   4A          LSR
080C-   4A          LSR
080D-   09 C0       ORA   #$C0
080F-   85 3F       STA   $3F
0811-   A9 5C       LDA   #$5C
0813-   85 3E       STA   $3E
0815-   18          CLC
0816-   AD FE 08    LDA   $08FE
0819-   6D FF 08    ADC   $08FF
081C-   8D FE 08    STA   $08FE
081F-   AE FF 08    LDX   $08FF
0822-   F0 15       BEQ   $0839
0824-   8A          TXA

; well, mostly standard
0825-   EA          NOP
0826-   EA          NOP
0827-   85 3D       STA   $3D
0829-   CE FF 08    DEC   $08FF
082C-   AD FE 08    LDA   $08FE
082F-   85 27       STA   $27
0831-   CE FE 08    DEC   $08FE
0834-   A6 2B       LDX   $2B
0836-   6C 3E 00    JMP   ($003E)

; execution continues here after sector
; read loop exits (from $0822)
0839-   EE FE 08    INC   $08FE
083C-   EE FE 08    INC   $08FE
083F-   20 89 FE    JSR   $FE89
0842-   20 93 FE    JSR   $FE93
0845-   20 2F FB    JSR   $FB2F

; copy this sector (which we didn't
; re-read) to higher memory
0848-   A2 FF       LDX   #$FF
084A-   BD 00 08    LDA   $0800,X
084D-   9D 00 B6    STA   $B600,X
0850-   CA          DEX
0851-   E0 FF       CPX   #$FF
0853-   D0 F5       BNE   $084A

; hmm
0855-   20 CC 08    JSR   $08CC

*8CCL

; trash all of main memory except the
; part we just loaded from disk
08CC-   A9 00       LDA   #$00
08CE-   85 00       STA   $00
08D0-   A9 B5       LDA   #$B5
08D2-   85 01       STA   $01
08D4-   A0 FF       LDY   #$FF
08D6-   C8          INY
08D7-   B9 00 F0    LDA   $F000,Y
08DA-   91 00       STA   ($00),Y
08DC-   C0 FF       CPY   #$FF
08DE-   D0 F6       BNE   $08D6
08E0-   C6 01       DEC   $01
08E2-   A9 08       LDA   #$08
08E4-   C5 01       CMP   $01
08E6-   D0 EC       BNE   $08D4
08E8-   60          RTS

Continuing from $0858...

*858L

0858-   A6 2B       LDX   $2B
085A-   4C 00 BB    JMP   $BB00

OK, that's where I need to interrupt
the boot. But first I'll need to neuter
the subroutine at $08CC that trashes
all of main memory.

*9600<C600.C6FFM

; disable memory wipe
96F8-   A9 60       LDA   #$60
96FA-   8D CC 08    STA   $08CC

; set up callback instead of continuing
; to $B700
96FD-   A9 0A       LDA   #$0A
96FF-   8D 5B 08    STA   $085B
9702-   A9 97       LDA   #$97
9704-   8D 5C 08    STA   $085C

; start the boot
9707-   4C 01 08    JMP   $0801

; (callback is here) copy the code to
; lower memory so it survives a reboot
970A-   A2 0A       LDX   #$0A
970C-   A0 00       LDY   #$00
970E-   B9 00 B6    LDA   $B600,Y
9711-   99 00 26    STA   $2600,Y
9714-   C8          INY
9715-   D0 F7       BNE   $970E
9717-   EE 10 97    INC   $9710
971A-   EE 13 97    INC   $9713
971D-   CA          DEX
971E-   D0 EE       BNE   $970E

; turn off drive motor
9720-   AD E8 C0    LDA   $C0E8

; reboot to my work disk
9723-   4C 00 C5    JMP   $C500

*BSAVE TRACE,A$9600,L$126
*9600G
...reboots slot 6...
...reboots slot 5...

]BSAVE BOOT1,A$2600,L$A00

                   ~

               Chapter 2
     In Which We Hit Our Head, But
  We're In Such Unfriendly Territory
  That Nobody Is There To Comfort Us


]CALL -151

*FE89G FE93G     ; disconnect DOS
*B600<2600.2FFFM ; move RWTS into place
*BB00L

BB00-   A9 46       LDA   #$46
BB02-   8D 78 04    STA   $0478
BB05-   A6 2B       LDX   $2B
BB07-   A9 00       LDA   #$00
BB09-   85 03       STA   $03
BB0B-   8D 78 04    STA   $0478
BB0E-   E6 03       INC   $03
BB10-   E6 03       INC   $03
BB12-   A5 03       LDA   $03
BB14-   C9 46       CMP   #$46
BB16-   F0 09       BEQ   $BB21

; move drive head (accumulator holds
; phase, which is track x2)
BB18-   20 A0 B9    JSR   $B9A0

; hmm
BB1B-   20 29 BB    JSR   $BB29

; unconditional branch
BB1E-   18          CLC
BB1F-   90 ED       BCC   $BB0E

; execution continues here (from $BB16)
; move drive head back to track $00
BB21-   A9 00       LDA   #$00
BB23-   20 A0 B9    JSR   $B9A0

; continue elsewhere
BB26-   4C 00 BC    JMP   $BC00

This is the subroutine that executes on
every track:

*BB29L

; initialize death counter
BB29-   A0 75       LDY   #$75
BB2B-   88          DEY

; if Y hits 0, give up
BB2C-   F0 1C       BEQ   $BB4A

; look for a specific nibble sequence
BB2E-   BD 8C C0    LDA   $C08C,X
BB31-   10 FB       BPL   $BB2E
BB33-   C9 CB       CMP   #$CB
BB35-   D0 F4       BNE   $BB2B
BB37-   BD 8C C0    LDA   $C08C,X
BB3A-   10 FB       BPL   $BB37
BB3C-   C9 DC       CMP   #$DC
BB3E-   D0 EB       BNE   $BB2B
BB40-   BD 8C C0    LDA   $C08C,X
BB43-   10 FB       BPL   $BB40
BB45-   C9 BC       CMP   #$BC
BB47-   D0 E2       BNE   $BB2B
BB49-   60          RTS

; failure path (from $BB2C)
; on track $01, try again (seems like a
; kludge)
BB4A-   A5 03       LDA   $03
BB4C-   C9 02       CMP   #$02
BB4E-   F0 D9       BEQ   $BB29

; otherwise destroy everything and hang
BB50-   E6 01       INC   $01
BB52-   91 00       STA   ($00),Y
BB54-   C8          INY
BB55-   F0 F9       BEQ   $BB50
BB57-   D0 F9       BNE   $BB52

Well that seems unfriendly. Continuing
at $BC00...

*BC00L

; nibble check part 2?
BC00-   A6 2B       LDX   $2B
BC02-   9D 8E C0    STA   $C08E,X
BC05-   9D 8C C0    STA   $C08C,X
BC08-   A0 00       LDY   #$00

; read nibbles and compare to a given
; sequence
BC0A-   BD 8C C0    LDA   $C08C,X
BC0D-   10 FB       BPL   $BC0A
BC0F-   D9 44 BC    CMP   $BC44,Y
BC12-   F0 02       BEQ   $BC16
BC14-   D0 F2       BNE   $BC08
BC16-   C8          INY
BC17-   C0 04       CPY   #$04
BC19-   D0 EF       BNE   $BC0A

; and again
BC1B-   A0 00       LDY   #$00
BC1D-   BD 8C C0    LDA   $C08C,X
BC20-   10 FB       BPL   $BC1D
BC22-   D9 48 BC    CMP   $BC48,Y
BC25-   F0 02       BEQ   $BC29
BC27-   D0 F2       BNE   $BC1B
BC29-   C8          INY
BC2A-   C0 06       CPY   #$06
BC2C-   D0 EF       BNE   $BC1D

; and again
BC2E-   A0 00       LDY   #$00
BC30-   BD 8C C0    LDA   $C08C,X
BC33-   10 FB       BPL   $BC30
BC35-   D9 4E BC    CMP   $BC4E,Y
BC38-   F0 02       BEQ   $BC3C
BC3A-   D0 F2       BNE   $BC2E
BC3C-   C8          INY
BC3D-   C0 03       CPY   #$03
BC3F-   D0 EF       BNE   $BC30

; success path continues at $B700
BC41-   4C 00 B7    JMP   $B700

OK, there don't appear to be any side
effects; I can probably just bypass the
entire thing.

                   ~

               Chapter 3
In Which We Attempt To Use The Original
    Disk As A Weapon Against Itself


$B700 looks more or less like DOS 3.3
boot1, except it starts reading DOS at
T02,S0A. But more importantly, $B800+
appears to be a DOS 3.3-shaped RWTS.
Here, for example, is the code to match
the Panglossian address prologue:

*B94FL

; prologue #1 = $CD
B94F-   BD 8C C0    LDA   $C08C,X
B952-   10 FB       BPL   $B94F
B954-   C9 CD       CMP   #$CD
B956-   D0 F0       BNE   $B948
B958-   EA          NOP

; doesn't actually care what the second
; prologue nibble is
B959-   BD 8C C0    LDA   $C08C,X
B95C-   10 FB       BPL   $B959
B95E-   C9 EC       CMP   #$EC
B960-   EA          NOP
B961-   EA          NOP
B962-   A0 03       LDY   #$03

; prologue #3 = $BC
B964-   BD 8C C0    LDA   $C08C,X
B967-   10 FB       BPL   $B964
B969-   C9 BC       CMP   #$BC
B96B-   D0 E7       BNE   $B954

Thus...

[S6,D1=original disk]
[S6,D2=blank disk]
[S5,D1=my work disk]

]BRUN ADVANCED DEMUFFIN 1.5

[press "5" to switch to slot 5]

[press "R" to load a new RWTS module]
  --> At $B6, load "BOOT1" from drive 1

[press "6" to switch to slot 6]

[press "C" to convert disk]

--> CHANGE DEFAULT VALUES? Y

                 --v--

ADVANCED DEMUFFIN 1.5    (C) 1983, 2014
ORIGINAL BY THE STACK    UPDATES BY 4AM
=======================================


INPUT ALL VALUES IN HEX


SECTORS PER TRACK? (13/16) 16

START TRACK: $01        <-- change this
START SECTOR: $00

END TRACK: $22
END SECTOR: $0F

INCREMENT: 1

MAX # OF RETRIES: 0

COPY FROM DRIVE 1
TO DRIVE: 2
=======================================
16SC $01,$00-$22,$0F BY1.0 S6,D1->S6,D2

                 --^--

Now press RETURN to start the copy...

                 --v--

ADVANCED DEMUFFIN 1.5    (C) 1983, 2014
ORIGINAL BY THE STACK    UPDATES BY 4AM
=======PRESS ANY KEY TO CONTINUE=======
TRK: .R................................
+.5:
    0123456789ABCDEF0123456789ABCDEF012
SC0: ..................................
SC1: ..................................
SC2: ..................................
SC3: ..................................
SC4: ..................................
SC5: ..................................
SC6: ..................................
SC7: ..................................
SC8: ..................................
SC9: ..................................
SCA: ..................................
SCB: .R................................
SCC: .R................................
SCD: .R................................
SCE: .R................................
SCF: .R................................
=======================================
16SC $01,$00-$22,$0F BY$01 S6,D1->S6,D2

                 --^--

Oh what fresh hell is this.

Never mind, we'll look into it later.

]PR#5
...
]CATALOG,S6,D2

C1983 DSR^C#254
050 FREE

 A 002 BOOTUP
*A 004 HELLO
*B 034 AQUARIUS.PIC
*A 025 PART 1
*A 023 PART 2
*A 015 PART 2 CONT
*A 024 PART 3
*A 025 PART 3 CONT
*A 020 PART 3 CONT 1
*A 021 PART 4
*A 018 PART 4 CONT
*A 019 PART 4 CONT 1
*B 016 ALPHA.L106
 A 025 P1
 A 023 P2
 A 015 P2C
 A 019 P3
 A 025 P3C
 A 020 P3C1
 A 021 P4
 A 018 P4C
 A 019 P4C1
 A 015 HELLO-BOOTUP

(Which is the startup program, BOOTUP,
HELLO, HELLO-BOOTUP, or something else?
Looking at the demuffin'd disk with my
trusty Disk Fixer sector, it appears to
be HELLO-BOOTUP. It's usually stored on
T01,S09, but here it's T01,S0F because
the entire DOS is shifted to fit on
tracks $01/$02 and avoid track $00.)

]RUN HELLO-BOOTUP
...works...

(The reason I always do this is to see
whether there are any runtime checks
for subtle differences in the original
DOS. If the program runs after booting
from a third-party disk, I can
eliminate a whole range of possible
secondary protections.)

Now to make the disk be able to read
itself. (Remember, it still has the
original RWTS on it.) As a bonus, this
will also destroy the nibble check at
$BB00.

[Copy ][+ 8.4]
  --> COPY
    --> DOS
      --> from slot 6, drive 2
      -->   to slot 6, drive 1

[S6,D1=demuffin'd copy]
[S6,D2=newly formatted DOS 3.3 disk]

...read read read...
...write write write...

[Copy ][+ 8.4]
  --> CHANGE BOOT PROGRAM
    --> slot 6, drive 1
      --> "HELLO-BOOTUP"

]PR#6
...works...

What about the bad sectors on track 2?
  They're unformatted and unused. The
  DOS is loaded from T02,S0A backwards,
  but the entire track is marked as
  used in the disk catalog VTOC.

Disks 2-4 use identical protection,
except that on disks 3 and 4, the
startup program is HELLO.

Quod erat liberandum.

---------------------------------------
A 4am crack                     No. 612
------------------EOF------------------
